#include "bind_func.h"

int std_function() {
    std::function<void(void)> fr1 = func;
    fr1();

    Foo foo;
    std::function<void(void)> fr2 = foo;
    fr2();

    std::function<void(int, float)> fr3 = A::func;
    fr3(2, 3.14);

    Bar bar;
    std::function<void(int, float)> fr4 = (Bar::fr_t)bar;
    fr4(2, 3.14);

    return 0;
}

int std_function_callback() {
    Foo foo;
    CallBack cb(foo);
    cb.notify();

    return 0;
}

int std_function_condition_call() {
    for (int i = 0; i < 10; i++) {
        call_when_even(i, output);
    }
    std::cout << std::endl;
    return 0;
}

int std_bind() {
    // 1. 将两个参数的函数绑定为没有参数的可以调用对象
    {
        auto fr = std::bind(some_func, 1, 2);
        fr();
    }

    {
        // std::placeholders::_1代表这个位置将在函数调用时, 被传入的第一个参数替代
        // std::placeholders::_1占在第二个位置, 2是输入参数的第一个值
        // 因此输出1, 2
        auto fr = std::bind(some_func, 1, std::placeholders::_1);
        fr(2);
    }


    {
        // 输出1, 2
        auto fr = std::bind(some_func, std::placeholders::_1, 2);
        fr(1);
    }


    {
        // 输出4, 2
        auto fr = std::bind(some_func, std::placeholders::_2, 2);
        fr(1, 4);
    }

    // 统计大于2的值的数量
    std::vector<int> arr;
    int count = std::count_if(arr.begin(), arr.end(), 
            std::bind(std::greater<int>(), std::placeholders::_1, 2));


    return 0;
}

int std_bind_class() {
    // 创建一个Foo对象
    Foo foo;
    // 创建一个CallBack对象，并将foo对象作为参数传入
    CallBack a(foo);
    // 定义一个std::function对象fr，使用std::bind函数将CallBack对象的notify函数与a对象绑定
    std::function<void(void)> fr = std::bind(&CallBack::notify, &a);

    // 调用fr对象
    fr();

    // 返回0
    return 0;
}